#!/bin/bash

# 测试删除同步功能的脚本
# 验证主节点删除后，从节点是否正确同步删除

set -e

# 配置
LEADER_HOST="localhost"
LEADER_PORT=8080
FOLLOWER_HOST="localhost"
FOLLOWER_PORT=8081

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log() {
    echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}

success() {
    echo -e "${GREEN}✓${NC} $1"
}

error() {
    echo -e "${RED}✗${NC} $1"
}

warning() {
    echo -e "${YELLOW}⚠${NC} $1"
}

# 检查节点状态
check_node_status() {
    local host=$1
    local port=$2
    local name=$3
    
    log "检查 $name 节点状态..."
    
    if curl -s "http://$host:$port/admin/health" > /dev/null 2>&1; then
        success "$name 节点运行正常"
        return 0
    else
        error "$name 节点不可访问"
        return 1
    fi
}

# 创建测试文件
create_test_file() {
    local path=$1
    local content=$2
    
    log "在主节点创建文件: $path"
    
    response=$(curl -s -w "%{http_code}" -X POST \
        -H "Content-Type: application/json" \
        -d "{\"path\":\"$path\", \"content\":\"$content\"}" \
        "http://$LEADER_HOST:$LEADER_PORT/file/create")
    
    http_code="${response: -3}"
    if [ "$http_code" = "200" ]; then
        success "文件创建成功: $path"
        return 0
    else
        error "文件创建失败: $path (HTTP $http_code)"
        return 1
    fi
}

# 创建测试目录
create_test_directory() {
    local path=$1
    
    log "在主节点创建目录: $path"
    
    response=$(curl -s -w "%{http_code}" -X POST \
        -H "Content-Type: application/json" \
        -d "{\"path\":\"$path\"}" \
        "http://$LEADER_HOST:$LEADER_PORT/directory/create")
    
    http_code="${response: -3}"
    if [ "$http_code" = "200" ]; then
        success "目录创建成功: $path"
        return 0
    else
        error "目录创建失败: $path (HTTP $http_code)"
        return 1
    fi
}

# 删除文件或目录
delete_path() {
    local path=$1
    local recursive=${2:-false}
    
    log "在主节点删除: $path (recursive=$recursive)"
    
    response=$(curl -s -w "%{http_code}" -X DELETE \
        "http://$LEADER_HOST:$LEADER_PORT/file/delete?path=$path&recursive=$recursive")
    
    http_code="${response: -3}"
    if [ "$http_code" = "200" ]; then
        success "删除成功: $path"
        return 0
    else
        error "删除失败: $path (HTTP $http_code)"
        return 1
    fi
}

# 检查文件是否存在
check_file_exists() {
    local host=$1
    local port=$2
    local path=$3
    local node_name=$4
    
    response=$(curl -s -w "%{http_code}" \
        "http://$host:$port/file/info?path=$path")
    
    http_code="${response: -3}"
    if [ "$http_code" = "200" ]; then
        return 0  # 文件存在
    else
        return 1  # 文件不存在
    fi
}

# 等待同步完成
wait_for_sync() {
    local max_wait=30
    local wait_time=0
    
    log "等待同步完成..."
    
    while [ $wait_time -lt $max_wait ]; do
        sleep 2
        wait_time=$((wait_time + 2))
        
        # 检查从节点同步状态
        sync_status=$(curl -s "http://$FOLLOWER_HOST:$FOLLOWER_PORT/admin/sync-status" 2>/dev/null || echo "error")
        if [[ "$sync_status" != "error" ]]; then
            log "等待同步... (${wait_time}s/${max_wait}s)"
        fi
    done
    
    success "同步等待完成"
}

# 测试单个文件删除
test_single_file_delete() {
    log "=== 测试单个文件删除 ==="
    
    # 创建测试文件
    create_test_file "/test_file.txt" "This is a test file for delete sync"
    
    # 等待同步
    wait_for_sync
    
    # 检查文件在两个节点都存在
    if check_file_exists $LEADER_HOST $LEADER_PORT "/test_file.txt" "Leader"; then
        success "主节点文件存在"
    else
        error "主节点文件不存在"
        return 1
    fi
    
    if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "/test_file.txt" "Follower"; then
        success "从节点文件存在"
    else
        error "从节点文件不存在"
        return 1
    fi
    
    # 在主节点删除文件
    delete_path "/test_file.txt"
    
    # 等待同步
    wait_for_sync
    
    # 检查文件在两个节点都不存在
    if check_file_exists $LEADER_HOST $LEADER_PORT "/test_file.txt" "Leader"; then
        error "主节点文件仍然存在（应该已删除）"
        return 1
    else
        success "主节点文件已删除"
    fi
    
    if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "/test_file.txt" "Follower"; then
        error "从节点文件仍然存在（应该已删除）"
        return 1
    else
        success "从节点文件已删除"
    fi
    
    success "单个文件删除测试通过"
}

# 测试目录递归删除
test_recursive_directory_delete() {
    log "=== 测试目录递归删除 ==="
    
    # 创建测试目录结构
    create_test_directory "/test_dir"
    create_test_directory "/test_dir/subdir"
    create_test_file "/test_dir/file1.txt" "File 1 content"
    create_test_file "/test_dir/subdir/file2.txt" "File 2 content"
    
    # 等待同步
    wait_for_sync
    
    # 检查目录结构在两个节点都存在
    paths_to_check=(
        "/test_dir"
        "/test_dir/subdir" 
        "/test_dir/file1.txt"
        "/test_dir/subdir/file2.txt"
    )
    
    for path in "${paths_to_check[@]}"; do
        if check_file_exists $LEADER_HOST $LEADER_PORT "$path" "Leader"; then
            success "主节点 $path 存在"
        else
            error "主节点 $path 不存在"
            return 1
        fi
        
        if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "$path" "Follower"; then
            success "从节点 $path 存在"
        else
            error "从节点 $path 不存在"
            return 1
        fi
    done
    
    # 递归删除整个目录
    delete_path "/test_dir" true
    
    # 等待同步
    wait_for_sync
    
    # 检查所有路径在两个节点都不存在
    for path in "${paths_to_check[@]}"; do
        if check_file_exists $LEADER_HOST $LEADER_PORT "$path" "Leader"; then
            error "主节点 $path 仍然存在（应该已删除）"
            return 1
        else
            success "主节点 $path 已删除"
        fi
        
        if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "$path" "Follower"; then
            error "从节点 $path 仍然存在（应该已删除）"
            return 1
        else
            success "从节点 $path 已删除"
        fi
    done
    
    success "目录递归删除测试通过"
}

# 测试空目录删除
test_empty_directory_delete() {
    log "=== 测试空目录删除 ==="
    
    # 创建空目录
    create_test_directory "/empty_dir"
    
    # 等待同步
    wait_for_sync
    
    # 检查目录在两个节点都存在
    if check_file_exists $LEADER_HOST $LEADER_PORT "/empty_dir" "Leader"; then
        success "主节点空目录存在"
    else
        error "主节点空目录不存在"
        return 1
    fi
    
    if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "/empty_dir" "Follower"; then
        success "从节点空目录存在"
    else
        error "从节点空目录不存在"
        return 1
    fi
    
    # 删除空目录
    delete_path "/empty_dir"
    
    # 等待同步
    wait_for_sync
    
    # 检查目录在两个节点都不存在
    if check_file_exists $LEADER_HOST $LEADER_PORT "/empty_dir" "Leader"; then
        error "主节点空目录仍然存在（应该已删除）"
        return 1
    else
        success "主节点空目录已删除"
    fi
    
    if check_file_exists $FOLLOWER_HOST $FOLLOWER_PORT "/empty_dir" "Follower"; then
        error "从节点空目录仍然存在（应该已删除）"
        return 1
    else
        success "从节点空目录已删除"
    fi
    
    success "空目录删除测试通过"
}

# 显示同步状态
show_sync_status() {
    log "=== 同步状态信息 ==="
    
    echo "Leader 同步状态:"
    curl -s "http://$LEADER_HOST:$LEADER_PORT/admin/sync-status" | jq . 2>/dev/null || echo "无法获取状态"
    
    echo "Follower 同步状态:"
    curl -s "http://$FOLLOWER_HOST:$FOLLOWER_PORT/admin/sync-status" | jq . 2>/dev/null || echo "无法获取状态"
}

# 主函数
main() {
    log "开始删除同步功能测试"
    
    # 检查节点状态
    if ! check_node_status $LEADER_HOST $LEADER_PORT "Leader"; then
        error "Leader 节点不可用，测试终止"
        exit 1
    fi
    
    if ! check_node_status $FOLLOWER_HOST $FOLLOWER_PORT "Follower"; then
        error "Follower 节点不可用，测试终止"
        exit 1
    fi
    
    # 显示同步状态
    show_sync_status
    
    # 执行测试
    local tests_passed=0
    local total_tests=3
    
    if test_single_file_delete; then
        tests_passed=$((tests_passed + 1))
    fi
    
    if test_empty_directory_delete; then
        tests_passed=$((tests_passed + 1))
    fi
    
    if test_recursive_directory_delete; then
        tests_passed=$((tests_passed + 1))
    fi
    
    # 显示最终结果
    log "=== 测试结果 ==="
    if [ $tests_passed -eq $total_tests ]; then
        success "所有测试通过！($tests_passed/$total_tests)"
        success "删除同步功能工作正常"
    else
        error "部分测试失败 ($tests_passed/$total_tests)"
        error "删除同步功能存在问题"
        exit 1
    fi
    
    # 显示最终同步状态
    show_sync_status
}

# 执行主函数
main "$@"
